package org.testis.webautomationmodule.ui.objects;

import org.testis.data.AtofModuleConstants;
import org.testis.logging.AtofLogLevel;
import org.testis.utils.StringVerification;
import org.testis.webautomationmodule.ui.UIElementNotFoundException;
import org.testis.webautomationmodule.ui.UIFormFieldDecorator;

public class UIDropDown extends UIFormFieldDecorator {

    private String[] m_valueList;

    public UIDropDown(String id) {
        super(id);
    }

    public UIDropDown(String id,
            String value) {
        super(id,
                value);
        setValueList(value.split(
                AtofModuleConstants.PARAM_SEP_SPLIT_STR));

    }

    public String[] getValueList() {
        return m_valueList;
    }

    public void setValueList(String[] val) {
        this.m_valueList = val;
    }

    @Override
    protected boolean setBehavior() {
        if (checkAvailableForAction()) {
            if (checkExistence(getValue(),
                    getAllOptionsLabels())) {
                select("label=" + getValue());
            } else if (checkExistence(getValue(),
                    getAllOptionsIds())) {
                select("id=" + getValue());
            } else if (checkExistence(getValue(),
                    getAllOptionsValues())) {
                select("value=" + getValue());
            } else {
                throw new UIElementNotFoundException(" Option " + getValue()
                        + " not found in dropdown with id "
                        + getId());
            }
            return true;
        }
        return true;
    }

    @Override
    public boolean verifyBehavior() {
        String curValue = "", curId = "", curLabel = "";
        if (checkAvailableForVerification()) {
            if (getValue().startsWith(AtofModuleConstants.CONTAINS_STR)) {
                return checkContainsValidation();
            } else if (getValue().startsWith("!=" + AtofModuleConstants.CONTAINS_STR)) {
                return !checkContainsValidation();
            } else if (getValue().startsWith(AtofModuleConstants.LIST_BOX_EMPTY_STR)) {
                return checkEmtpyValidation();
            } else if (getValue().startsWith("!=" + AtofModuleConstants.LIST_BOX_EMPTY_STR)) {
                return !checkEmtpyValidation();
            }
            curValue = getSelectedValue();
            curId = getSelectedId();
            curLabel = getSelectedLabel();
            if (StringVerification.verifyText(getValue(), curValue)) {
                putLog(" Object with " + getId()
                        + " id was  verified... curValue:" + curValue
                        + " compared with:"
                        + getValue());
                setValue(curValue);
                return true;
            } else if (StringVerification.verifyText(getValue(), curId)) {
                putLog(" Object with " + getId()
                        + " id was  verified... curId:" + curId
                        + " compared with:"
                        + getValue());
                setValue(curId);
                return true;
            } else if (StringVerification.verifyText(getValue(), curLabel)) {
                putLog(" Object with " + getId()
                        + " id was  verified... curLabel:" + curLabel
                        + " compared with:"
                        + getValue());
                setValue(curLabel);
                return true;
            } else {
                putLog(" Object with " + getId()
                        + " id was  not verified... curLabel:" + curLabel
                        + " curId:" + curId + " curValue:" + curValue
                        + " compared with:"
                        + getValue(),
                        AtofLogLevel.ERROR);
                setValue(curLabel);
            }

        } else {
            putLog(" Object with " + getId()
                    + " id was not available for verification...",
                    AtofLogLevel.ERROR);
            setValue(null);
        }
        return false;
    }

    private boolean checkEmtpyValidation() {
        String curValue = getArrayAsString(getAllOptionsValues());
        if (curValue.isEmpty()) {
            return true;
        }
        return false;
    }

    private boolean checkContainsValidation() {
        String values = "";
        if (getValue().startsWith("!=")) {
            values = getValue().replace("!=" + AtofModuleConstants.CONTAINS_STR,
                    "");
        } else {
            values = getValue().replace(AtofModuleConstants.CONTAINS_STR,
                    "");
        }
        int startIdx = values.indexOf("(");
        int endIdx = values.lastIndexOf(")");
        if (startIdx >= 0 && endIdx > 0) {
            values = values.substring(startIdx + 1,
                    endIdx);
            String[] valueList = values.split(
                    AtofModuleConstants.PARAM_SEP_SPLIT_STR);
            setValueList(valueList);
            String curValue = "", curIds = "", curLabels = "";
            curValue = getArrayAsString(getAllOptionsValues());
            curIds = getArrayAsString(getAllOptionsIds());
            curLabels = getArrayAsString(getAllOptionsLabels());
            if (checkValidation(getAllOptionsLabels())) {
                putLog(" Object with " + getId()
                        + " id contains given values...curLabels :" + curValue
                        + " compared with:"
                        + values);
                setValue(curValue);
                return true;
            } else if (checkValidation(getAllOptionsValues())) {
                putLog(" Object with " + getId()
                        + " id contains given values... curValues:" + curIds
                        + " compared with:"
                        + values);
                setValue(curIds);
                return true;
            } else if (checkValidation(getAllOptionsIds())) {
                putLog(" Object with " + getId()
                        + " id contains given values... curIds:" + curLabels
                        + " compared with:"
                        + values);
                setValue(curLabels);
                return true;
            } else {
                putLog(" Object with " + getId()
                        + " id does not contains given values... curLabels:"
                        + curLabels
                        + "curIds:" + curIds + "curValues:" + curValue
                        + " compared with:"
                        + values, AtofLogLevel.ERROR);
                setValue(curLabels);
                return false;
            }

        } else {
            putLog("  UIDropDown Object with " + getId()
                    + " id  was not verified...Given value parameter is not valid for contains statement:"
                    + getValue(),
                    AtofLogLevel.ERROR);
            return false;
        }
    }

    public String getArrayAsString(String[] arr) {
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < arr.length; i++) {
            if (i > 0) {
                result.append(AtofModuleConstants.PARAM_SEP_STR);
            }
            result.append(arr[i]);
        }
        return result.toString();
    }

    private boolean checkValidation(String[] compareArr) {
        boolean verified = true;
        for (int i = 0; i < getValueList().length; i++) {
            boolean isFound = false;
            for (int j = 0; j < compareArr.length; j++) {
                if (StringVerification.verifyText(getValueList()[i].trim(), compareArr[j].trim())) {
                    isFound = true;
                    break;
                }
            }
            if (!isFound) {
                verified = false;
                break;
            }
        }
        return verified;
    }

    @Override
    public boolean getBehavior() {
        if (checkAvailableForVerification()) {
            setValue(getSelectedLabel());
        }
        putLog("Gets value of UIDropDown with id="
                + getId() + " value=" + getValue());
        return true;
    }

    private boolean checkExistence(String val,
            String[] arr) {
        for (int i = 0; i < arr.length; i++) {
            if (StringVerification.verifyText(val, arr[i])) {
                setValue(arr[i]);
                return true;
            }
        }
        return false;
    }

    private String[] getAllOptionsLabels() {
        return getWebAutomationImpl().getSelectOptions(getId());
    }

    private String[] getAllOptionsValues() {
        String script =
                "function getSelectValues(){var values='';"
                + "var options=selenium.browserbot.getDocument().getElementById('"
                + getId()
                + "').options;"
                + "for (i = 0; i < options.length; i++){"
                + "   if(values==''){ values=options[i].value.toString(); }"
                + "   else {values=values+'"
                + AtofModuleConstants.PARAM_SEP_STR
                + "'+options[i].value.toString();}"
                + "} return values};  eval('getSelectValues()');";
        String output = getWebAutomationImpl().getEval(script);
        return output.split(AtofModuleConstants.PARAM_SEP_SPLIT_STR);
    }

    private String[] getAllOptionsIds() {
        String script =
                "function getSelectIds(){var values='';"
                + "var options=selenium.browserbot.getDocument().getElementById('"
                + getId()
                + "').options;"
                + "for (i = 0; i < options.length; i++){"
                + "   if(values==''){ values=options[i].id.toString(); }"
                + "   else {values=values+'"
                + AtofModuleConstants.PARAM_SEP_STR
                + "'+options[i].id.toString();}"
                + "} return values};  eval('getSelectIds()');";
        String output = getWebAutomationImpl().getEval(script);
        return output.split(AtofModuleConstants.PARAM_SEP_SPLIT_STR);
    }

    private String getSelectedValue() {
        return getWebAutomationImpl().getSelectedValue(getId());
    }

    private String getSelectedLabel() {
        return getWebAutomationImpl().getSelectedLabel(getId());
    }

    private String getSelectedId() {
        return getWebAutomationImpl().getSelectedId(getId());
    }

    private void select(String optionId) {
        getWebAutomationImpl().select(getId(),
                optionId);
        getWebAutomationImpl().click(getId());
        putLog(" selecting option (" + optionId
                + ") for the single-select object with id " + getId());
    }
}

